// 版权所有2011 Go作者。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package bzip2

// moveToFrontDecoder实现移动到前端列表。这样的一份清单是一个很好的例子
// 将具有重复元素的字符串转换为具有重复元素的字符串的有效方法
// 许多小值数，适合于熵编码。它起作用了
// 从符号和参考的初始列表开始，按符号的
// 索引到该列表中。当符号被引用时，它将移动到前面
// 在名单上。因此，一个重复的符号最终被编码为许多零，
// 因为第一次访问后，符号将位于列表的前面。
type moveToFrontDecoder []byte

// newMTFDecoder使用显式初始列表创建移动到前端解码器
// 象征的象征。
func newMTFDecoder(symbols []byte) moveToFrontDecoder {
	if len(symbols) > 256 {
		panic("too many symbols")
	}
	return moveToFrontDecoder(symbols)
}

// newMTFDecoderWithRange创建一个带有初始值的移动到前端解码器
// 0…n-1的符号列表。
func newMTFDecoderWithRange(n int) moveToFrontDecoder {
	if n > 256 {
		panic("newMTFDecoderWithRange: cannot have > 256 symbols")
	}

	m := make([]byte, n)
	for i := 0; i < n; i++ {
		m[i] = byte(i)
	}
	return moveToFrontDecoder(m)
}

func (m moveToFrontDecoder) Decode(n int) (b byte) {
	// 用一个简单的拷贝实现移动到前面。这种方法
	// 可能比基准测试中更复杂的方法要好
	// 因为它在
	// 单缓存线（大多数向前移动操作的n<64）。
	b = m[n]
	copy(m[1:], m[:n])
	m[0] = b
	return
}

// 首先返回列表前面的符号。
func (m moveToFrontDecoder) First() byte {
	return m[0]
}
